﻿using RAP.Framework.Libary.DomTemplateBuilder.Attributes;
using RAP.Framework.Libary.DomTemplateBuilder.Handler.Conditional;
using RAP.Framework.Libary.ExpressionCompiler;
using RAP.Framework.Libary.Utils;
using System;
using System.Collections.Generic;
using System.Text;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;

namespace RAP.Framework.Libary.DomTemplateBuilder.Element.Conditional
{
  /// <summary>
  /// if条件节点
  /// </summary>
  [TagHandler(typeof(IfHandler))]
  public class If : Dynamic, IElseElement, IElseIfElement, IExpressionElement
  {
    /// <summary>
    /// “否则”分支
    /// </summary>
    public virtual Else Else
    {
      get;
      set;
    }

    /// <summary>
    /// 表达式节点
    /// </summary>
    public virtual Expression ExpressionElement
    {
      get;
      set;
    }

    /// <summary>
    /// “否则-如果”分支集合，一个If节点可包含多个ElseIf节点
    /// </summary>
    public virtual IList<ElseIf> ElseIfs { get; } = new List<ElseIf>();

    private string _expression = null;
    /// <summary>
    /// 条件表达式
    /// </summary>
    public virtual string Expression
    {
      get
      {
        if (_expression.IsNullOrEmpty())
        {
          _expression = this.ToString("Expression", string.Empty);
        }
        return _expression;
      }
      set
      {
        this["Expression"] = _expression = value;
      }
    }

    private Func<object, object, object, bool> _expressionHandler = null;

    /// <summary>
    /// 获取编译后的表达式执行Handler
    /// </summary>
    /// <param name="rootParamObject"></param>
    /// <param name="parentParamObject"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public virtual Func<object, object, object, bool> GetExpressionHandler(object rootParamObject, object parentParamObject, ITemplateRenderContext context)
    {
      if (_expressionHandler == null)
      {
        lock (this)
        {
          if (_expressionHandler == null)
          {
            var exp = this.Expression;
            if (exp.IsNullOrEmpty())
            {
              if (this.ExpressionElement != null)
              {
                var writer = new StringBuilder();
                this.ExpressionElement.Handler.DoRender(writer, rootParamObject, parentParamObject, context);
                exp = writer.ToString();
              }
            }
            else
            {
              exp = ExpressionUtils.ParseCSharpExpression(exp);
            }
            if (exp.IsNullOrEmpty())
            {
              throw new NullReferenceException("表达式不能为null或空字符串！");
            }
            try
            {
              _expressionHandler = CSCompiler.CompileDelegate<Func<dynamic, dynamic, dynamic, bool>>($"return {exp};", "param,parent,context");
            }
            catch (Exception ex)
            {
              Console.WriteLine(ex.Message);
              throw new Exception("If节点表达式语法错误！");
            }
          }
        }
      }
      return _expressionHandler;
    }
  }
}
